/*-------------------------------------------------------------------------
 *
 * scankey.c
 *	  扫描键支持代码
 *
 * Portions Copyright (c) 1996-2022, PostgreSQL Global Development Group
 * Portions Copyright (c) 1994, Regents of the University of California
 *
 *
 * IDENTIFICATION
 *	  src/backend/access/common/scankey.c
 *
 *-------------------------------------------------------------------------
 */
#include "postgres.h"

#include "access/skey.h"
#include "catalog/pg_collation.h"


/*
 * ScanKeyEntryInitialize
 *		初始化扫描键条目，给定所有字段值。
 *		目标过程通过OID指定（但如果设置了SK_SEARCHNULL或SK_SEARCHNOTNULL可能是无效的）。
 *
 * 注意：调用时的CurrentMemoryContext应与ScanKey本身一样长久，
 * 因为这将用于任何附加到ScanKey的FmgrInfo记录的附属信息。
 */
void ScanKeyEntryInitialize(ScanKey fc_entry,
					   int fc_flags,
					   AttrNumber fc_attributeNumber,
					   StrategyNumber fc_strategy,
					   Oid fc_subtype,
					   Oid fc_collation,
					   RegProcedure fc_procedure,
					   Datum fc_argument)
{
	fc_entry->sk_flags = fc_flags;
	fc_entry->sk_attno = fc_attributeNumber;
	fc_entry->sk_strategy = fc_strategy;
	fc_entry->sk_subtype = fc_subtype;
	fc_entry->sk_collation = fc_collation;
	fc_entry->sk_argument = fc_argument;
	if (RegProcedureIsValid(fc_procedure))
	{
		fmgr_info(fc_procedure, &fc_entry->sk_func);
	}
	else
	{
		Assert(fc_flags & (SK_SEARCHNULL | SK_SEARCHNOTNULL));
		MemSet(&fc_entry->sk_func, 0, sizeof(fc_entry->sk_func));
	}
}

/*
 * ScanKeyInit
 *		ScanKeyEntryInitialize的简写版本：标志和子类型
 *		假定为零（通常值），排序规则默认为默认值。
 *
 * 这是在系统目录中硬编码查找的推荐版本。
 * 它无法处理NULL参数、一元运算符或非默认运算符，
 * 但对于大多数硬编码查找我们不需要那些功能。
 *
 * 我们始终将排序规则设置为C_COLLATION_OID。这是系统目录中
 * 所有排序感知列的正确值，对于其他列类型将被忽略，
 * 所以不值得尝试更为苛求。
 *
 * 注意：调用时的CurrentMemoryContext应与ScanKey本身一样长久，
 * 因为这将用于任何附加到ScanKey的FmgrInfo记录的附属信息。
 */
void ScanKeyInit(ScanKey fc_entry,
			AttrNumber fc_attributeNumber,
			StrategyNumber fc_strategy,
			RegProcedure fc_procedure,
			Datum fc_argument)
{
	fc_entry->sk_flags = 0;
	fc_entry->sk_attno = fc_attributeNumber;
	fc_entry->sk_strategy = fc_strategy;
	fc_entry->sk_subtype = InvalidOid;
	fc_entry->sk_collation = C_COLLATION_OID;
	fc_entry->sk_argument = fc_argument;
	fmgr_info(fc_procedure, &fc_entry->sk_func);
}

/*
 * ScanKeyEntryInitializeWithInfo
 *		使用已完成的FmgrInfo
 *		函数查找记录初始化扫描键条目。
 *
 * 注意：调用时的CurrentMemoryContext应与ScanKey本身一样长久，
 * 因为这将用于任何附加到ScanKey的FmgrInfo记录的附属信息。
 */
void ScanKeyEntryInitializeWithInfo(ScanKey fc_entry,
							   int fc_flags,
							   AttrNumber fc_attributeNumber,
							   StrategyNumber fc_strategy,
							   Oid fc_subtype,
							   Oid fc_collation,
							   FmgrInfo *fc_finfo,
							   Datum fc_argument)
{
	fc_entry->sk_flags = fc_flags;
	fc_entry->sk_attno = fc_attributeNumber;
	fc_entry->sk_strategy = fc_strategy;
	fc_entry->sk_subtype = fc_subtype;
	fc_entry->sk_collation = fc_collation;
	fc_entry->sk_argument = fc_argument;
	fmgr_info_copy(&fc_entry->sk_func, fc_finfo, CurrentMemoryContext);
}
